import { LitElement, svg, css, html } from 'lit';
import { classMap } from 'lit/directives/class-map.js';
import { createRef, ref } from 'lit/directives/ref.js';

/**
 * 对原生 audio 标签的简单封装，同时支持在线音频与 Anki 音频。
 * 
 * @example
 * // 播放在线音频
 * <ac-audio src="https://example.com/audio.mp3"></ac-audio>
 * 
 * // 播放 Anki 音频
 * <ac-audio>{{音频字段}}</ac-audio>
 * 
 * // 如果一个字段即可能是 Anki 音频，又可能是在线地址，可以使用如下写法
 * <ac-audio>{{音频字段}}</ac-audio>
 */
class ACAudio extends LitElement {
  static properties = {
    /**
     * @type {string} src 音频地址
     */
    src: {
      type: String,
      hasChanged: (newVal, oldVal) => {
        const REGEX = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*)/g;
        if (newVal.match(REGEX))
          this._trueSrc = newVal;
        else
          this._trueSrc = '';
        console.log(this._trueSrc);
        return true;
      }
    },
    /**
     * @type {boolean} 是否自动播放
     */
    autoplay: { type: Boolean },
    _isDarkMode: { type: Boolean },
    _trueSrc: { type: String },
    _isPlaying: { type: Boolean },
    _isLoading: { type: Boolean },
    _ankiCommand: { type: String },
  };

  audio = createRef();

  static styles = css`
      .replay-button {
        text-decoration: none;
        display: inline-flex;
        vertical-align: middle;
        margin: 3px;
      }

      .replay-button svg {
        width: 40px;
        height: 40px;
      }

      .replay-button svg circle {
        fill: #fff;
        stroke: #414141;
      }

      .dark.replay-button svg path {
        fill: #414141;
      }

      .dark.replay-button svg circle {
        fill: #fff;
        stroke: #414141
      }

      .dark.replay-button svg path {
        fill: #414141
      }
    `;

  constructor() {
    super();

    this.isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
    window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
      this.isDarkMode = e.matches;
    });
    this._isPlaying = false;
    this._isLoading = false;
  }

  firstUpdated() {
    super.firstUpdated();
    if (this.autoplay) {
      this.play();
    }
  }

  disconnectedCallback() {
    super.disconnectedCallback();

  }

  connectedCallback() {
    super.connectedCallback();
    this._processInnerContent();
  }

  _processInnerContent() {
    if (!this.src) {
      const innerContent = this.innerHTML.trim();
      const urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z]{2,6})([\/\w\.-]*)*\/?$/g;
      const ankiRegex = /onclick="([^"]+)"/g;

      if (urlRegex.test(innerContent)) {
        this._trueSrc = innerContent.match(urlRegex)[0];
      } else if (ankiRegex.test(innerContent)) {
        ankiRegex.lastIndex = 0;
        const match = ankiRegex.exec(innerContent);
        if (match && match[1]) {
          this._ankiCommand = match[1];
          this._trueSrc = '';
        }
      }
    }
  }

  render() {
    const classes = {
      dark: this.isDarkMode,
    };

    const playIcon = svg`
      <path d="M 26 20 L 26 44 L 45 32 L 26 20" stroke="#414141" stroke-width="2" fill="#414141"></path>
    `;

    const pauseIcon = svg`
      <path d="M40,20h-4c-1.1,0-2,0.9-2,2v20c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V22C42,20.9,41.1,20,40,20z M28,20h-4c-1.1,0-2,0.9-2,2v20 c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V22C30,20.9,29.1,20,28,20z" fill="#414141"></path>
    `;

    const loadingIcon = svg`
      <g>
        <path d="M 32 16 A 16 16 0 0 1 48 32" stroke="#414141" stroke-width="6" fill="none" />
        <animateTransform
          attributeName="transform"
          attributeType="XML"
          type="rotate"
          dur="1s"
          from="0 32 32"
          to="360 32 32"
          repeatCount="indefinite"/>
      </g>
    `;
    return html`
      <a class="replay-button soundLink ${classMap(classes)}" href="#" @click=${this.play}>
        <svg class="playImage" viewBox="0 0 64 64" version="1.1">
          <circle cx="32" cy="32" r="29"></circle>
          ${this._isLoading ? loadingIcon : (this._isPlaying ? pauseIcon : playIcon)}
        </svg>
      </a>
      <audio 
        ${ref(this.audio)}
        src="${this.src}" 
        @playing=${this._handlePlaying}
        @pause=${this._handlePause}
        @waiting=${this._handleWaiting}
        @ended=${this._handleEnded}
      ></audio>
    `;
  }

  _handlePlaying() {
    this._isPlaying = true;
    this._isLoading = false;
  }

  _handlePause() {
    this._isPlaying = false;
    this._isLoading = false;
  }

  _handleWaiting() {
    this._isLoading = true;
  }

  _handleEnded() {
    this._isPlaying = false;
    this._isLoading = false;
  }

  play() {
    if (this._ankiCommand) {
      eval(`(() => {${this._ankiCommand}})()`);
      return;
    }
    // if (this.audio.value.src !== this._trueSrc) {
    //   this.audio.value.src = this._trueSrc;
    // }
    if (this._isPlaying) {
      this.audio.value.pause();
    } else {
      this.audio.value.play();
    }
  }
}

customElements.define('ac-audio', ACAudio);

export { ACAudio };
